﻿using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace FBGraph
{
    /// <summary>Contains base functionality for FBGraph controllers, which provide access to the various
    /// objects and connections in the Graph API.</summary>
    public class FBGraphController : IFBGraphController
    {
        private static Dictionary<Type, String[]> FieldNames;
        private static readonly Object FieldNamesLock = new Object();

        /// <summary>Initializes an instance of <see cref="FBGraphController" />.</summary>
        /// <param name="context">A reference to the containing <see cref="IFBGraphContext" /> implementation.</param>
        protected FBGraphController(IFBGraphContext context)
        {
            this.Context = context;
            this.InitSubcontrollers();
        }

        /// <summary>Gets a reference to the containing <see cref="IFBGraphContext" /> implementation.</summary>
        protected IFBGraphContext Context { get; private set; }
        /// <summary>Gets a reference to the containing <see cref="IFBGraphContext" /> implementation.</summary>
        IFBGraphContext IFBGraphController.Context { get { return this.Context; } }

        /// <summary>In derived classes, initializes any subcontrollers contained by the <see cref="FBGraphController" /> implementation.</summary>
        protected virtual void InitSubcontrollers() { }

        String[] IFBGraphController.GetFields()
        {
            if (FBGraphController.FieldNames == null)
            {
                lock (FBGraphController.FieldNamesLock)
                {
                    if (FBGraphController.FieldNames == null)
                    {
                        FBGraphController.FieldNames = new Dictionary<Type, String[]>();
                    }
                }
            }

            var type = this.GetType();
            if (!FBGraphController.FieldNames.ContainsKey(type))
            {
                lock (FBGraphController.FieldNamesLock)
                {
                    if (!FBGraphController.FieldNames.ContainsKey(type))
                    {
                        var custom = (SelectAttribute)type.GetCustomAttributes(typeof(SelectAttribute), false).SingleOrDefault();
                        if (custom == null)
                        {
                            FBGraphController.FieldNames.Add(type, null);
                        }
                        else
                        {
                            FBGraphController.FieldNames.Add(type, custom.Fields);
                            return custom.Fields;
                        }
                    }
                }
            }

            return FBGraphController.FieldNames[type];
        }
    }
}